home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume22 / pty / part03 < prev    next >
Encoding:
Internet Message Format  |  1990-10-09  |  54.5 KB

  1. Subject:  v23i033:  Run a program under a pty session, Part03/06
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: d7df909f c513140f bb00a2fe 82998f8c
  5.  
  6. Submitted-by: Dan Bernstein <brnstnd@kramden.acf.nyu.edu>
  7. Posting-number: Volume 23, Issue 33
  8. Archive-name: pty/part03
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then feed it
  12. # into a shell via "sh file" or similar.  To overwrite existing files,
  13. # type "sh file -c".
  14. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  15. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  16. # Contents:  config.h logs.c pty.1 sigler.c sock.c tty.c util/Makefile
  17. # Wrapped by rsalz@litchi.bbn.com on Wed Oct 10 10:11:38 1990
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. echo If this archive is complete, you will see the following message:
  20. echo '          "shar: End of archive 3 (of 6)."'
  21. if test -f 'config.h' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'config.h'\"
  23. else
  24.   echo shar: Extracting \"'config.h'\" \(9610 characters\)
  25.   sed "s/^X//" >'config.h' <<'END_OF_FILE'
  26. X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
  27. X
  28. X#ifndef PTY_CONFIG_H
  29. X#define PTY_CONFIG_H
  30. X
  31. X/* It is recommended that you make local changes in the Makefile, */
  32. X/* except for feature control, which is best done here. */
  33. X
  34. X/* Section 1: Feature control. */
  35. X/* Section 2: Pseudo-terminal pathnames. */
  36. X/* Section 3: Logging. */
  37. X/* Section 4: Protection. */
  38. X/* Section 5: Other. */
  39. X/* Section 6: Sanity checks. */
  40. X
  41. X/* Each section starts with the necessary defines and finishes with */
  42. X/* an explanation. */
  43. X
  44. X
  45. X/* Section 1: Feature control. */
  46. X
  47. X/*#define MUST_UTMP  /* force utmp logging */
  48. X/*#define NO_UTMP  /* prohibit utmp logging */
  49. X/*#define MUST_WTMP  /* force utmp logging */
  50. X/*#define NO_WTMP  /* prohibit wtmp logging */
  51. X/*#define MUST_SESSION  /* force disconnectable sessions (what for?) */
  52. X/*#define NO_SESSION  /* prohibit disconnectable sessions */
  53. X/*#define MUST_CHOWN  /* force changing pty owner */
  54. X/*#define NO_CHOWN  /* prohibit changing pty owner */
  55. X/*#define NO_FDPASSING  /* prohibit file descriptor passing */
  56. X/*#define NO_UNIXSOCKS  /* prohibit use of UNIX-domain sockets */
  57. X#define TTY_WINDOWS  /* have winsize, WINCH, etc. in tty (4.3) */
  58. X/*#define TTY_AUXCHARS  /* have systat, e.g. with ^T, in tty */
  59. X#define DESPERATE_ALARMS  /* if NDELAY may not be enough */
  60. X#define DONT_NDELAY  /* might as well, with DESPERATE_ALARMS */
  61. X#define SIGINTERRUPT  /* if you have siginterrupt() (4.3) */
  62. X#define USLEEP  /* if you have usleep() */
  63. X
  64. X/* These are mostly self-explanatory. If your system doesn't support */
  65. X/* some feature, you should prohibit it by defining NO_WHATEVER. */
  66. X
  67. X/* Any BSD 4.2 or 4.3 system should have UNIXSOCKS and FDPASSING. Look */
  68. X/* for /sys/h/un.h to see if you have UNIX-domain sockets. Look for */
  69. X/* msg_accrights in the man page for recvmsg() to see if you have */
  70. X/* file desriptor passing. (Sometimes fd passing is available but buggy, */
  71. X/* as it's a relatively new, powerful, and rarely exploited feature. In */
  72. X/* this case you should define NO_FDPASSING.) In the current version, */
  73. X/* NO_UNIXSOCKS implies NO_FDPASSING and NO_SESSION; see Section 6. */
  74. X
  75. X/* For TTY_WINDOWS, look for struct winsize in /usr/include/sgtty.h. */
  76. X/* For TTY_AUXCHARS, look for struct auxchars in the same place. */
  77. X/* All BSD 4.3 systems should have winsize; auxchars isn't so common. */
  78. X
  79. X/* Opening the slave side of a pty without a master should hang the */
  80. X/* process. Normally, opening with NDELAY gets around this effect; */
  81. X/* opening the slave side first is necessary for some security checks. */
  82. X/* On some systems, however, NDELAY doesn't do its job; you must */
  83. X/* define DESPERATE_ALARMS to forcibly interrupt each open(). There */
  84. X/* shouldn't be any problem in leaving this (and DONT_NDELAY) defined */
  85. X/* anyway. (On a few systems, you must have DONT_NDELAY for -xn.) */
  86. X
  87. X/* Define SIGINTERRUPT if you have siginterrupt() (i.e., if you're */
  88. X/* running BSD 4.3). Without this call, there's no correct way to do */
  89. X/* per-process nonblocking I/O, and pty may block when it shouldn't */
  90. X/* (namely, when it has N bytes to write to the output, the output is */
  91. X/* a blocking pipe with M bytes of space, and N > M > 0). If you define */
  92. X/* SIGINTERRUPT, pty will take some extra effort to never, ever, ever */
  93. X/* block when it doesn't have to. (See OUTBUFSIZE, below.) */
  94. X
  95. X/* Define USLEEP if you have usleep(). */
  96. X
  97. X
  98. X/* Section 2: Pathnames. */
  99. X
  100. X#ifndef PTYDIR
  101. X#define PTYDIR "/usr/etc/pty"
  102. X#endif
  103. X#ifndef DEVMTY
  104. X#define DEVMTY "/dev/pty  "
  105. X#endif
  106. X#ifndef DEVSTY
  107. X#define DEVSTY "/dev/tty  "
  108. X#endif
  109. X#ifndef PTY1
  110. X#define PTY1 "pqrstuvwxyzabcdefghijklmno"
  111. X#endif
  112. X#ifndef PTY2
  113. X#define PTY2 "0123456789abcdef"
  114. X#endif
  115. X#ifndef TTYNAMELEN
  116. X#define TTYNAMELEN 30
  117. X#endif
  118. X
  119. X/* PTYDIR is where pty sessions store their information. You should */
  120. X/* create it mode 700, owner pty, group irrelevant. You must define */
  121. X/* PTYDIR as something even if you don't allow sessions. If you don't */
  122. X/* set up PTYDIR at all but you do allow sessions, pty will switch */
  123. X/* out of setuid after grabbing a pty, then set up session information */
  124. X/* in the user's home directory. This isn't totally secure but it's */
  125. X/* at least partially workable. */
  126. X
  127. X/* DEVMTY and DEVSTY are the basenames of the master and slave ptys */
  128. X/* respectively. They must each end with two spaces, filled in with */
  129. X/* characters from PTY1 and PTY2 respectively. If your ptys aren't */
  130. X/* labelled by this convention, I'm surprised you have anything working; */
  131. X/* either set up a new pty bank with normal names or change the pty code */
  132. X/* that allocates ptys. Note that convention allows you to only have */
  133. X/* some of a pty bank, as long as one of them is there; the first letter */
  134. X/* in PTY2 must indicate that one. */
  135. X
  136. X/* The order of PTY1 and PTY2 is the pty searching order. pty allows */
  137. X/* (and, as a break from tradition, uses by default) random searches, */
  138. X/* starting from random spots in PTY1 and PTY2 rather than the beginning. */
  139. X/* This has several good effects, although you may think utmp will look */
  140. X/* a bit ugly. */
  141. X
  142. X/* If you want to gradually convert your system to using this program, */
  143. X/* PTY1 and PTY2 shouldn't reference all your ptys. Instead, pick a */
  144. X/* large enough subset of your ptys to be usable, and try things out */
  145. X/* with just those. If everything works and you like pty's capabilities, */
  146. X/* remove your old ptys, or recompile pty to reference all of them. */
  147. X
  148. X/* TTYNAMELEN should be the maximum length of a tty (not just pty!) */
  149. X/* name. TTYNAMELEN shouldn't have to be there; it's used to work */
  150. X/* around some fundamental failures in the current tty/pty model. */
  151. X
  152. X
  153. X/* Section 3: Logging. */
  154. X
  155. X#ifndef PTYUTMP_FILE
  156. X#define PTYUTMP_FILE "/etc/utmp"
  157. X#endif
  158. X#ifndef PTYWTMP_FILE
  159. X#define PTYWTMP_FILE "/usr/adm/wtmp"
  160. X#endif
  161. X#ifndef PTYUTMP_OFFSET
  162. X#define PTYUTMP_OFFSET 5
  163. X#endif
  164. X#ifndef PTYWTMP_OFFSET
  165. X#define PTYWTMP_OFFSET PTYUTMP_OFFSET
  166. X#endif
  167. X#ifndef PTYUTMP_HOST
  168. X#define PTYUTMP_HOST "pty"
  169. X#endif
  170. X#ifndef PTYWTMP_HOST
  171. X#define PTYWTMP_HOST PTYUTMP_HOST
  172. X#endif
  173. X#ifndef PTYUTMP_SWHOST
  174. X#define PTYUTMP_SWHOST PTYUTMP_HOST
  175. X#endif
  176. X#ifndef PTYWTMP_SWHOST
  177. X#define PTYWTMP_SWHOST "pty-sessuser"
  178. X#endif
  179. X
  180. X/* These are straightforward. FILE is where you want the logs. utmp and */
  181. X/* wtmp are about as sensible as /etc/passwd and unfortunately just as */
  182. X/* popular; typically they're in /etc/utmp and /usr/adm/wtmp, and the */
  183. X/* utility programs in this package support that convention. (wtmp logs */
  184. X/* all ins and outs. utmp only has one entry per line, namely the last */
  185. X/* wtmp entry for it.) OFFSET is the number of chars from a pty extension */
  186. X/* to remove from a log entry; usually this is 5, to make /dev/ttyxx into */
  187. X/* ttyxx. Finally, HOST is the name that you want in the ``remote'' field */
  188. X/* of the log; that field is rather illogical, but it's there. */
  189. X
  190. X/* SWHOST is a variant of HOST, for what's logged upon a session uid */
  191. X/* switch. */
  192. X
  193. X/* If you're using pty under telnet/login/whatever, which do their own */
  194. X/* utmp and wtmp handling, then pty will usually have -xUW, so these */
  195. X/* defines aren't too important. Except for SWHOST, which is necessary */
  196. X/* for sessuser's action to make sense. */
  197. X
  198. X
  199. X/* Section 4: Protection. */
  200. X
  201. X#ifndef USEDPTYMODE
  202. X#define USEDPTYMODE 0600
  203. X#endif
  204. X#ifndef UNUSEDPTYMODE
  205. X#define UNUSEDPTYMODE 0600
  206. X#endif
  207. X#ifndef PTYOWNER
  208. X#define PTYOWNER euid
  209. X#endif
  210. X#ifndef PTYGROUP
  211. X#define PTYGROUP 4
  212. X#endif
  213. X
  214. X/* pty -xc will change the owner of the pty back to PTYOWNER after the */
  215. X/* child has exited. This should be euid, for the effective uid of the */
  216. X/* pty process. If a user runs pty as himself, he won't get to change */
  217. X/* the owner of the pseudo-terminal in the first place. */
  218. X
  219. X/* PTYGROUP should be the ``tty'' group in /etc/group, normally 4. All */
  220. X/* ptys and ttys should be in this group at all times. */
  221. X
  222. X/* USEDPTYMODE is the mode of ptys while they're being used. 600 is a */
  223. X/* good choice; it means messages off. If you want msgs y by default, */
  224. X/* try 620. Don't use the old 622: it's exceedingly insecure. */
  225. X
  226. X/* UNUSEDPTYMODE is the mode of ptys while they're unused. Traditionally */
  227. X/* this would be 666, so that any process needing a pty can just grab */
  228. X/* one. However, this leads to quite a few security holes. If you have */
  229. X/* lots of programs like emacs that really, really, really want to use */
  230. X/* ptys and don't support this interface, try 0660, and make those */
  231. X/* programs setgid tty. Otherwise, stick to 0600. */
  232. X
  233. X
  234. X/* Section 5: Other. */
  235. X
  236. X#ifndef SIGRET_TYPE
  237. X#define SIGRET_TYPE int
  238. X#endif
  239. X
  240. X#ifndef OUTBUFSIZE
  241. X#define OUTBUFSIZE 16384
  242. X#endif
  243. X
  244. X#ifndef GENERIC
  245. X#define GENERIC char
  246. X#endif
  247. X
  248. X#ifdef TTY_AUXCHARS
  249. X#define USESTAT
  250. X#endif
  251. X
  252. X/* SIGRET_TYPE is the type returned by signal handlers. Logically, it */
  253. X/* should be void, but C and signals were around before void was. */
  254. X
  255. X/* OUTBUFSIZE is the size of the extra buffers provided by pty, both */
  256. X/* for data coming in to the pseudo-terminal and for data going out. */
  257. X
  258. X/* It should be possible to cast any pointer to a GENERIC * pointer */
  259. X/* and back. Again, void makes the most sense and is the best choice */
  260. X/* under ANSI, but char is correct and much more portable. */
  261. X
  262. X/* Setting USESTAT is necessary for systems supporting auxchars. */
  263. X
  264. X
  265. X/* Section 6: Sanity checks. */
  266. X
  267. X#ifdef NO_UNIXSOCKS
  268. X#define NO_FDPASSING
  269. X#define NO_SESSION
  270. X#endif
  271. X
  272. X#ifdef NO_SESSION
  273. X#ifdef MUST_SESSION
  274. X#undef MUST_SESSION
  275. X#endif
  276. X#endif
  277. X
  278. X#ifdef NO_UTMP
  279. X#ifdef MUST_UTMP
  280. X#undef MUST_UTMP
  281. X#endif
  282. X#endif
  283. X
  284. X#ifdef NO_WTMP
  285. X#ifdef MUST_WTMP
  286. X#undef MUST_WTMP
  287. X#endif
  288. X#endif
  289. X
  290. X#ifdef NO_CHOWN
  291. X#ifdef MUST_CHOWN
  292. X#undef MUST_CHOWN
  293. X#endif
  294. X#endif
  295. X
  296. X#endif
  297. END_OF_FILE
  298.   if test 9610 -ne `wc -c <'config.h'`; then
  299.     echo shar: \"'config.h'\" unpacked with wrong size!
  300.   fi
  301.   # end of 'config.h'
  302. fi
  303. if test -f 'logs.c' -a "${1}" != "-c" ; then 
  304.   echo shar: Will not clobber existing file \"'logs.c'\"
  305. else
  306.   echo shar: Extracting \"'logs.c'\" \(1853 characters\)
  307.   sed "s/^X//" >'logs.c' <<'END_OF_FILE'
  308. X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
  309. X
  310. X#include "config.h"
  311. X#include "logs.h"
  312. X#include "file.h"
  313. X#include <utmp.h>
  314. X#include <strings.h>
  315. X
  316. X/* utmp and wtmp are about as sensible as /etc/passwd. */
  317. X
  318. X/* We never bother to shrink /etc/utmp. */
  319. X
  320. Xextern long time();
  321. X
  322. Xlong now()
  323. X{
  324. X return time((long *) 0);
  325. X}
  326. X
  327. Xint utmp(line,name,host,date)
  328. Xchar *line;
  329. Xchar *name;
  330. Xchar *host;
  331. Xlong date;
  332. X{
  333. X struct utmp ut;
  334. X struct utmp xt;
  335. X int fd;
  336. X int i;
  337. X int j;
  338. X
  339. X /* only use of strncpy, ever */
  340. X (void) strncpy(ut.ut_line,line,sizeof(ut.ut_line));
  341. X (void) strncpy(ut.ut_name,name,sizeof(ut.ut_name));
  342. X (void) strncpy(ut.ut_host,host,sizeof(ut.ut_host));
  343. X ut.ut_time = date;
  344. X
  345. X fd = open(PTYUTMP_FILE,O_RDWR);
  346. X if (fd == -1)
  347. X   return -1;
  348. X j = i = 0;
  349. X while (read(fd,(char *) &xt,sizeof(xt)) == sizeof(xt))
  350. X  {
  351. X   i++;
  352. X   if (strncmp(xt.ut_line,ut.ut_line,sizeof(ut.ut_line)) == 0)
  353. X    {
  354. X     j = i;
  355. X     break;
  356. X    }
  357. X  }
  358. X if (j)
  359. X  {
  360. X   if (lseek(fd,(long) ((j - 1) * sizeof(xt)),L_SET) == -1)
  361. X    {
  362. X     (void) close(fd);
  363. X     return -1;
  364. X    }
  365. X  }
  366. X else
  367. X  {
  368. X   /* We have to reopen to avoid a race with other end-of-utmp entries. */
  369. X   (void) close(fd);
  370. X   if ((fd = open(PTYUTMP_FILE,O_RDWR | O_APPEND)) == -1)
  371. X     return -1;
  372. X  }
  373. X if (write(fd,(char *) &ut,sizeof(ut)) < sizeof(ut))
  374. X  {
  375. X   (void) close(fd);
  376. X   return -1;
  377. X  }
  378. X (void) close(fd);
  379. X return 0;
  380. X}
  381. X
  382. Xint wtmp(line,name,host,date)
  383. Xchar *line;
  384. Xchar *name;
  385. Xchar *host;
  386. Xlong date;
  387. X{
  388. X struct utmp wt;
  389. X int fd;
  390. X
  391. X (void) strncpy(wt.ut_line,line,sizeof(wt.ut_line));
  392. X (void) strncpy(wt.ut_name,name,sizeof(wt.ut_name));
  393. X (void) strncpy(wt.ut_host,host,sizeof(wt.ut_host));
  394. X wt.ut_time = date;
  395. X
  396. X fd = open(PTYWTMP_FILE,O_WRONLY | O_APPEND);
  397. X if (fd == -1)
  398. X   return -1;
  399. X if (write(fd,(char *) &wt,sizeof(wt)) < sizeof(wt))
  400. X  {
  401. X   (void) close(fd);
  402. X   return -1;
  403. X  }
  404. X (void) close(fd);
  405. X return 0;
  406. X}
  407. END_OF_FILE
  408.   if test 1853 -ne `wc -c <'logs.c'`; then
  409.     echo shar: \"'logs.c'\" unpacked with wrong size!
  410.   fi
  411.   # end of 'logs.c'
  412. fi
  413. if test -f 'pty.1' -a "${1}" != "-c" ; then 
  414.   echo shar: Will not clobber existing file \"'pty.1'\"
  415. else
  416.   echo shar: Extracting \"'pty.1'\" \(12049 characters\)
  417.   sed "s/^X//" >'pty.1' <<'END_OF_FILE'
  418. X.TH pty 1
  419. X.SH NAME
  420. Xpty \- run a program under a pseudo-terminal session
  421. X.SH SYNTAX
  422. Xpty
  423. X[
  424. X\fB\-qQvdDe3EjJsStT0\fI
  425. X] [
  426. X\fB\-F\fI
  427. X] [
  428. X\fB\-f\fIn
  429. X] [
  430. X\fB\-p\fI[cCdDeEnNrRsS0]
  431. X] [
  432. X\fB\-x\fI[cCeEnNoOrRsSuUwWxX]
  433. X] [
  434. X\fB\-ACHUVW\fI
  435. X]
  436. Xprogram
  437. X[
  438. Xarg ...
  439. X]
  440. X.SH DESCRIPTION
  441. X.I pty
  442. Xdetaches itself from its original
  443. Xterminal,
  444. Xallocates a pseudo-terminal,
  445. Xand runs
  446. X.I program
  447. Xon that pseudo-terminal
  448. Xwith any given arguments.
  449. X.I pty
  450. Xlets you easily disconnect from and reconnect to
  451. Xsessions;
  452. Xit has over fifty options for precise control,
  453. Xand is meant to act as the sole interface
  454. Xbetween pseudo-terminals and the rest of the system.
  455. X.PP
  456. XThere are a few very common invocations of
  457. X.I pty.
  458. XThe most common is just
  459. X.I pty program,
  460. Xwith no options;
  461. Xthis has several effects as described below.
  462. X.I pty \-s program
  463. Xsets up a disconnectable session;
  464. Xit is described further in
  465. X.I sess(1).
  466. X.I pty \-0 program
  467. Xisolates the rest of the world from
  468. X.I program
  469. Xin several ways;
  470. Xit is described further in
  471. X.I condom(1).
  472. X.PP
  473. XThe two next most commonly used options
  474. Xare 
  475. X.I\-d,
  476. Xif
  477. X.I pty
  478. Xis started without a controlling terminal;
  479. Xand
  480. X.I\-xu,
  481. Xwhich makes an entry in
  482. X/etc/utmp.
  483. X.PP
  484. XSome programs (such as
  485. X.I vi)
  486. Xdon't like taking input or output
  487. Xfrom a pipe; under
  488. X.I pty,
  489. Xthey won't notice a thing.
  490. XOther programs buffer as much output as possible
  491. Xif they're in a pipe;
  492. Xunder
  493. X.I pty,
  494. Xthey'll buffer at most a line of output.
  495. X.I pty
  496. Xis very careful to restore terminal modes upon
  497. Xstopping or exiting;
  498. Xa careless
  499. X.I program
  500. Xis shielded from your terminal.
  501. XOtherwise,
  502. X.I pty program
  503. Xshould feel just like
  504. X.I program.
  505. X.PP
  506. X.I pty
  507. Xchanges the original terminal to character-at-a-time
  508. X(raw, cbreak, and noecho) mode; it sets the pseudo-terminal to
  509. Xthe original mode. When
  510. X.I program
  511. Xfinishes,
  512. X.I pty
  513. Xwill set the original terminal back to its original mode.
  514. XAny mode changes on the pseudo-terminal will be lost.
  515. X.PP
  516. X.I pty
  517. Xsets file descriptor 0 to input from the
  518. Xpseudo-terminal, 1 and 2 to output.
  519. X.I pty
  520. Xalso supports the ``3 is /dev/tty'' convention:
  521. Xit sets up file descriptor 3 for input from, output to,
  522. Xand terminal commands for
  523. X/dev/tty
  524. X(not the original tty, but the pseudo tty).
  525. X.PP
  526. XOptions
  527. X.B ACHUVW
  528. Xprint the authorship notice,
  529. Xcopyright notice,
  530. Xhelp notice,
  531. Xshort usage summary,
  532. Xversion number,
  533. Xand warranty information respectively.
  534. X.PP
  535. X.I pty
  536. Xhas quite a few flags,
  537. Xprocessed left to right:
  538. X.TP 12
  539. X\fB\-d\fI
  540. X.I pty
  541. Xwill assume it is already detached from the terminal.
  542. XThis forces
  543. X.B\-T;
  544. Xit sets but doesn't force
  545. X.B\-J.
  546. XAlso, instead of copying pseudo-terminal modes from
  547. Xthe original terminal,
  548. X.I pty
  549. Xwill set up a generic new-discipline line-at-a-time mode.
  550. X.TP
  551. X\fB\-D\fI
  552. X.I pty
  553. Xwill assume that it is attached to a terminal (default).
  554. XThis sets
  555. X.B\-jt.
  556. X.TP
  557. X\fB\-e\fI
  558. XPreserve
  559. Xstandard error (file descriptor 2)
  560. Xand standard tty (file descriptor 3).
  561. X.TP
  562. X\fB\-3\fI
  563. XPreserve fd 3, but point fd 2 at the pseudo-terminal.
  564. X.TP
  565. X\fB\-E\fI
  566. XDirect both file descriptors to the pseudo-terminal (default).
  567. X(Actually,
  568. X.I pty
  569. Xwill point standard error at the tty by name,
  570. Xbut fd 3 at /dev/tty,
  571. Xso that various
  572. X.I ioctl()
  573. Xcommands on fd 3 will work.)
  574. XAlso close all higher-numbered file descriptors.
  575. X.TP
  576. X\fB\-j\fI
  577. XJob control (default): When
  578. X.I program
  579. Xstops,
  580. X.I pty
  581. Xstops.
  582. XWhen 
  583. X.I pty
  584. Xis restarted,
  585. Xit restarts
  586. X.I program.
  587. X.TP
  588. X\fB\-J\fI
  589. XNo job control.
  590. XIf
  591. X.I program
  592. Xstops,
  593. X.I pty
  594. Xwill ignore it
  595. X(though it will always restart it upon a reconnect).
  596. XThis behavior is much less
  597. Xantisocial than
  598. Xthe behavior of the previous
  599. X.I pty
  600. Xversion.
  601. X.TP
  602. X\fB\-t\fI
  603. X.I pty
  604. Xwill set the
  605. Xoriginal terminal to
  606. Xno-echo, character-at-a-time mode (default).
  607. X.TP
  608. X\fB\-T\fI
  609. X.I pty
  610. Xwill not touch the original terminal, if there is one.
  611. XIt is always dangerous to put two programs in a pipe if both
  612. Xchange tty modes;
  613. X.I pty,
  614. X.I vi,
  615. Xand
  616. X.I more
  617. Xare examples of such programs. If you use
  618. X.I pty
  619. Xin a pipe
  620. Xwith another tty-mode-changing program,
  621. Xmake sure to specify
  622. X.B\-0
  623. X(which is an abbreviation for
  624. X.B\-eSTp0)
  625. Xso that
  626. X.I pty
  627. Xwill neither affect nor be affected by the other program.
  628. XIf you use a pipe of ptys,
  629. Xyou should probably specify
  630. X.B\-0
  631. Xin all but one.
  632. X.TP
  633. X\fB\-s\fI
  634. XSession.
  635. XWhen the connection is hung up or manually disconnected,
  636. X.I pty
  637. Xwill patiently wait for a
  638. Xreconnection.
  639. X.I program
  640. Xwon't notice a thing.
  641. X.B\-s
  642. Xsets but does not force
  643. X.B\-xu.
  644. XIt forces
  645. X.B\-E.
  646. X.TP
  647. X\fB\-S\fI
  648. XNo session (default).
  649. XWhen the connection is hung up,
  650. X.I pty
  651. Xwill send a HUP to
  652. X.I program.
  653. X.B\-S
  654. Xsets but does not force
  655. X.B\-xU.
  656. X.TP
  657. X\fB\-q\fI
  658. XQuiet.
  659. X.I pty
  660. Xwill print absolutely nothing on standard error.
  661. XIt will communicate strange events through its exit code.
  662. X.TP
  663. X\fB\-Q\fI
  664. XNot quiet (default).
  665. X.I pty
  666. Xwill generate bits of chatter about interesting
  667. Xevents.
  668. X.TP
  669. X\fB\-v\fI
  670. XVerbose.
  671. X.I pty
  672. Xwill blabber on and on and on and on and on and on and on and on.
  673. XIt keeps going,
  674. Xand going,
  675. Xand going,
  676. Xand going ...
  677. X.TP
  678. X\fB\-f\fIfd
  679. XPass the master and slave sides of the pseudo-terminal
  680. Xup in file descriptor
  681. X.I fd.
  682. XThis is only available if your machine supports descriptor passing.
  683. X
  684. XThe protocol, from the point of view of the receiver (``controller''),
  685. Xis to pty_getch a character off the other side
  686. Xof the passing descriptor, perhaps check that it is a G,
  687. Xand pty_putgetint a G for the process id of the signaller
  688. X(the process to recieve a HUP if the connection drops);
  689. Xpty_getch a character, perhaps check that it is m,
  690. Xand pty_putgetfd an m for the master side of the pseudo-terminal;
  691. Xand similarly for s and the slave side. (These functions are all
  692. Xavailable in sock.c in the
  693. X.I pty
  694. Xsource code.)
  695. X
  696. XWhen the connection is dropped,
  697. X.I pty
  698. Xwill send up a period,
  699. Xfollowed by one pid and two new descriptors as above
  700. Xif it reconnects.
  701. XIn the meantime, the controller has full responsibility for
  702. Xperforming terminal I/O.
  703. X.TP
  704. X\fB\-F\fI
  705. XDo not pass anything (default).
  706. X.TP
  707. X\fB\-p\fImmm
  708. XSet the
  709. Xpseudo-terminal to modes specified by
  710. X.I m.
  711. XUnder
  712. X.B\-d,
  713. Xdefaults are taken from the
  714. Xcurrent terminal;
  715. Xunder
  716. X.B\-D,
  717. Xdefaults are as below.
  718. XPredefined modes:
  719. X.RS
  720. X.TP 5
  721. X.I c
  722. XSet cbreak (character-at-a-time) mode.
  723. X.TP
  724. X.I C
  725. XDo not set cbreak mode (default). 
  726. X.TP
  727. X.I d
  728. XUse the new discipline (default, breaking with tradition).
  729. X.TP
  730. X.I D
  731. XUse the old discipline, without job control or other fancy tty features.
  732. X.TP
  733. X.I e
  734. XEcho characters (default).
  735. X.TP
  736. X.I E
  737. XDo not echo.
  738. X.TP
  739. X.I n
  740. XChange return to newline (default).
  741. X.TP
  742. X.I N
  743. XDo not change return to newline.
  744. X.TP
  745. X.I r
  746. XSet raw mode: do not produce signals, and pass eight-bit characters.
  747. X.TP
  748. X.I R
  749. XSet non-raw (``cooked'') mode (default).
  750. X.TP
  751. X.I s
  752. XSet line editing modes appropriate for a screen (default).
  753. X.TP
  754. X.I S
  755. XDo not set crt line editing modes.
  756. X.TP
  757. X.I 0
  758. XAn abbreviation for pcEN.
  759. X.RE
  760. X.TP
  761. X\fB\-x\fIsss
  762. XUse security, experimental, or extended measures specified by
  763. X.I s.
  764. XSome of these may be required or disabled by your system administrator.
  765. XPredefined values:
  766. X.RS
  767. X.TP 5
  768. X.I c
  769. XChange the ownership and protections of the pty appropriately.
  770. XThis reflects several errors in the
  771. X.I pty
  772. Xmodel, but it's customary.
  773. X.TP
  774. X.I C
  775. XDo not change pty ownership (default).
  776. X.TP
  777. X.I e
  778. XOpen stderr write-only to the pseudo-terminal.
  779. XThis should be default, but such programs as
  780. X.I csh
  781. Xand
  782. X.I more
  783. Xinsist on reading from stderr and dying horribly
  784. Xif they fail.
  785. X.B\-xe
  786. Xis useless under
  787. X.B\-e.
  788. X.TP
  789. X.I E
  790. XOpen stderr for reading and writing (default).
  791. X.TP
  792. X.I u
  793. XEnter login name into /etc/utmp.
  794. XAs a rule of thumb,
  795. Xyou should do this for interactive sessions.
  796. X.TP
  797. X.I n
  798. XUse some heuristics to try to figure out if someone
  799. Xhas the pty open (default).
  800. X.TP
  801. X.I N
  802. XDon't worry about pre-opened ptys.
  803. X.TP
  804. X.I o
  805. XSame as
  806. X.B\-xn,
  807. Xbut go on to the next pseudo-terminal
  808. Xif this one is open.
  809. X.TP
  810. X.I O
  811. XDon't skip pre-opened ptys.
  812. X.TP
  813. X.I r
  814. XRandom pseudo-terminal searching (default).
  815. XThis can provide a huge boost to speed and security.
  816. XIt hasn't been used because programmers don't realize
  817. Xthe virtues of modularity, are consequently too lazy to
  818. Xwrite something like
  819. X.I pty,
  820. Xand don't want to take the effort for random pty searching
  821. Xin every program that uses pseudo-terminals.
  822. X.TP
  823. X.I R
  824. XStraight pty searching, from the bottom on up.
  825. X.TP
  826. X.I s
  827. XSetuid (default).
  828. X.I pty 
  829. Xwill use a common directory
  830. Xfor storing session information.
  831. X.TP
  832. X.I S
  833. XNot setuid.
  834. X.I pty
  835. Xwill revoke all privileges and
  836. Xuse a subdirectory of your HOME directory.
  837. X.TP
  838. X.I U
  839. XDo not use utmp (default).
  840. X.TP
  841. X.I w
  842. XMake an entry in /usr/adm/wtmp.
  843. XThis probably isn't a good idea for general use,
  844. Xas
  845. Xconnection time recorded in
  846. X.I wtmp
  847. Xis often pressed into unfortunate service as
  848. Xa senseless basis for charged computer time.
  849. X.TP
  850. X.I W
  851. XDo not use wtmp (default).
  852. X.TP
  853. X.I x
  854. XSet exclusive use on the pty.
  855. XNo processes can open the pty after this;
  856. X.I program
  857. Xcan't even reopen
  858. X/dev/tty!
  859. X(It can use file descriptor 3 instead.)
  860. XThis can be very important for security when
  861. X.I pty
  862. Xhas not been installed by the system administrator.
  863. XIt should be set all the time, but
  864. Xtoo many programs rely on a filename for the terminal.
  865. X.TP
  866. X.I X
  867. XDo not set exclusive use (default).
  868. X.RE
  869. X.PP
  870. X.SH DIAGNOSTICS
  871. X.TP
  872. Xvarious usage messages
  873. XExit 1.
  874. X.TP
  875. X.I fatal: cannot find control terminal
  876. X.I pty
  877. Xis unable to find its current control terminal.
  878. XExit 2.
  879. X.TP
  880. X.I fatal: cannot get current tty modes
  881. XThis shouldn't happen.
  882. XExit 3.
  883. X.TP
  884. X.I fatal: cannot set modes of original tty
  885. XThis shouldn't happen.
  886. XExit 4.
  887. X.TP
  888. X.I fatal: no ptys available
  889. XSelf-explanatory.
  890. XExit 5.
  891. X.TP
  892. X.I fatal: can't fcntl pty
  893. X.TP
  894. X.I fatal: slave unopenable
  895. XThere's a serious problem with your pseudo-terminal setup.
  896. XReport this error to your system administrator.
  897. XExit 6.
  898. X.TP
  899. X.I fatal: cannot fork
  900. X.I pty
  901. Xhas run out of processes.
  902. XExit 7.
  903. X.TP
  904. X.I fatal: cannot change to session directory
  905. XSelf-explanatory.
  906. XExit 8.
  907. X.TP
  908. X.I fatal: cannot open internal pipe.
  909. XCannot happen.
  910. XExit 10.
  911. X.TP
  912. X.I fatal: socket read error
  913. XSelf-explanatory. Exit 11.
  914. X.TP
  915. X.I fatal: socket write error
  916. XSelf-explanatory. Exit 12.
  917. X.TP
  918. X.I fatal: input read error
  919. XSelf-explanatory. Exit 13.
  920. X.TP
  921. X.I fatal: output write error
  922. XSelf-explanatory. Exit 14.
  923. X.SH RESTRICTIONS
  924. XThere are many security problems
  925. Xand limitations associated with BSD-style ttys.
  926. X.I pty
  927. Xdoes its best to avoid them,
  928. Xbut a Streams-based system would be much better.
  929. XThe author plans to rewrite
  930. X.I pty,
  931. Xwith the same interface,
  932. Xfor a Streams system.
  933. X.PP
  934. XThe current
  935. X.B\-J
  936. Xbehavior is a bit dull.
  937. XI wish programs would use the job control
  938. Xmechanisms more cleanly.
  939. X.PP
  940. XTo avoid a race condition,
  941. X.I pty
  942. Xchews up a tiny bit more CPU time than it should every
  943. Xtime
  944. X.I program
  945. Xis stopped and then restarted.
  946. X.PP
  947. XIf
  948. X.I program
  949. Xcloses the pseudo-terminal but doesn't die,
  950. X.I pty
  951. Xwill wait for it, even though it will have no further interaction with
  952. Xit.
  953. X.PP
  954. X.I pty
  955. Xdoes not provide any way to loudly proclaim that
  956. X.I program
  957. Xdoesn't exist.
  958. XIt simply dies quietly.
  959. X.PP
  960. XBecause of BSD's ridiculous controlling terminal mechanism,
  961. Xa reconnecting
  962. X.I pty
  963. Xhas to
  964. Xpass the name of its original terminal
  965. Xto the session underneath.
  966. XSince there is no portable way to find out that name,
  967. X.I pty
  968. Xrequires that some file descriptor be open, pointing
  969. Xto the current terminal
  970. X.I (not
  971. X/dev/tty!).
  972. X(More precisely,
  973. Xthe highest-numbered file descriptor that
  974. Xis a terminal file but not /dev/tty
  975. Xmust be the real name of the original controlling terminal.
  976. XThat's one good use for fd 3.
  977. XIf that file descriptor is some other terminal,
  978. Xthe reconnect will fail miserably.)
  979. X.SH BUGS
  980. XNone known, but they're probably hiding somewhere.
  981. XIt is the author's opinion that
  982. X.I pty
  983. Xis the ``right'' way to handle pseudo-terminals;
  984. Xif programmers use
  985. X.I pty
  986. Xinstead of writing equivalent code in each program,
  987. Xthen everything becomes much more portable and bug-free.
  988. XAs different systems provide different
  989. Xpseudo-terminal mechanisms,
  990. Xthe only program that need be changed is
  991. X.I pty.
  992. X(This is called ``modularity,''
  993. X``interface design,''
  994. Xor ``outside-in programming.'')
  995. X.SH MACHINES
  996. X.I pty
  997. Xhas been tested thoroughly
  998. Xon several BSD 4.3-based machines
  999. Xand tested on
  1000. Xseveral BSD 4.2-based machines.
  1001. X.SH VERSION
  1002. Xpty version 3.001, dated August 21, 1990.
  1003. X.SH AUTHOR
  1004. XCopyright 1990, Daniel J. Bernstein.
  1005. X.SH "SEE ALSO"
  1006. Xpty(4),
  1007. Xtty(4)
  1008. END_OF_FILE
  1009.   if test 12049 -ne `wc -c <'pty.1'`; then
  1010.     echo shar: \"'pty.1'\" unpacked with wrong size!
  1011.   fi
  1012.   # end of 'pty.1'
  1013. fi
  1014. if test -f 'sigler.c' -a "${1}" != "-c" ; then 
  1015.   echo shar: Will not clobber existing file \"'sigler.c'\"
  1016. else
  1017.   echo shar: Extracting \"'sigler.c'\" \(8120 characters\)
  1018.   sed "s/^X//" >'sigler.c' <<'END_OF_FILE'
  1019. X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
  1020. X
  1021. X#include "config.h"
  1022. X#include <sys/types.h>
  1023. X#include <sys/time.h>
  1024. X#include <stdio.h>
  1025. X#include <strings.h>
  1026. X#include "pty.h"
  1027. X#include "sigler.h"
  1028. X#include "sig.h"
  1029. X#include "file.h"
  1030. X#include "sock.h"
  1031. X#include "err.h"
  1032. X#include "misc.h"
  1033. X
  1034. X/* General XXX: In failure cases, sig.* isn't always removed. */
  1035. X
  1036. Xstatic char *glfnsty;
  1037. X
  1038. Xstatic int masterpid;
  1039. X
  1040. Xstatic int flagmaster = 1;
  1041. Xstatic int flagcont = 0;
  1042. Xstatic int pi[2];
  1043. X
  1044. Xstatic void deatherrp(i,s)
  1045. Xint i;
  1046. Xchar *s;
  1047. X{
  1048. X int e = errno;
  1049. X
  1050. X (void) kill(masterpid,SIGTERM);
  1051. X /* XXX: should wait while flagmaster */
  1052. X (void) tty_modifymodes(fdtty,&tmotty,&tmochartty);
  1053. X fatalerrp(i,s,e);
  1054. X}
  1055. X
  1056. Xstatic void finish(i)
  1057. Xsig_num i;
  1058. X{
  1059. X if (i == SIGTERM)
  1060. X  {
  1061. X   flagmaster = 0;
  1062. X   (void) write(pi[1],".",1);
  1063. X  }
  1064. X else
  1065. X   (void) write(pi[1],",",1);
  1066. X}
  1067. X
  1068. X/*ARGSUSED*/
  1069. Xstatic void sig_usr2(i)
  1070. Xsig_num i;
  1071. X{
  1072. X if (flagsession)
  1073. X  {
  1074. X   char fnsess[20];
  1075. X   int fdsess;
  1076. X   int newuid = uid;
  1077. X   char newsuid[10];
  1078. X
  1079. X   /* XXX: We should have some error recovery here! */
  1080. X
  1081. X   /* We can make quite a few assumptions, because we only get USR2 */
  1082. X   /* forwarded from the master. */
  1083. X
  1084. X   (void) sprintf(fnsess,"sess.%s",glfnsty + sizeof(DEVSTY) - 3);
  1085. X   if ((fdsess = open(fnsess,O_RDONLY,0600)) != -1)
  1086. X    {
  1087. X     (void) read(fdsess,(char *) &newuid,sizeof(int));
  1088. X     (void) sprintf(newsuid,"%d",newuid);
  1089. X
  1090. X     (void) chdir("..");
  1091. X     (void) chdir(newsuid);
  1092. X  
  1093. X     uid = newuid;
  1094. X     (void) setreuid(uid,euid);
  1095. X     (void) close(fdsess);
  1096. X    }
  1097. X  }
  1098. X}
  1099. X
  1100. X/*ARGSUSED*/
  1101. Xstatic void sig_cont(i)
  1102. Xsig_num i;
  1103. X{
  1104. X flagcont = 1;
  1105. X (void) write(pi[1]," ",1);
  1106. X}
  1107. X
  1108. Xvoid sigler(fnsty,master)
  1109. Xchar *fnsty;
  1110. Xint master;
  1111. X{
  1112. X char ch;
  1113. X char path[100];
  1114. X int fd = -1;
  1115. X char *ttyn;
  1116. X char fntty[TTYNAMELEN];
  1117. X
  1118. X glfnsty = fnsty;
  1119. X masterpid = master;
  1120. X /* pid = getpid() is already true */
  1121. X (void) sprintf(path,"sig.%s",fnsty + sizeof(DEVSTY) - 3);
  1122. X (void) unlink(path);
  1123. X
  1124. X (void) close(fdmty);
  1125. X (void) close(fdsty);
  1126. X if (fdre != -1) (void) close(fdre);
  1127. X
  1128. X if (pipe(pi) == -1) /* clumsy, but stops several races */
  1129. X   /* This is absolutely impossible. fdmty and fdsty must have been open */
  1130. X   /* before this, and we just closed them, so there must be two fds */
  1131. X   /* available for the pipe. */
  1132. X   deatherrp(10,"pty: fatal: cannot open internal pipe");
  1133. X (void) fcntl(pi[1],F_SETFL,FNDELAY);
  1134. X
  1135. X sig_ignore(SIGCHLD);
  1136. X sig_ignore(SIGXCPU);
  1137. X sig_ignore(SIGXFSZ);
  1138. X sig_ignore(SIGPROF);
  1139. X sig_ignore(SIGVTALRM);
  1140. X
  1141. X sig_default(SIGEMT); /* XXX: really dump? */
  1142. X sig_default(SIGIOT);
  1143. X sig_default(SIGILL);
  1144. X sig_default(SIGSEGV);
  1145. X
  1146. X sig_default(SIGTTOU);
  1147. X sig_default(SIGTTIN);
  1148. X sig_default(SIGTSTP);
  1149. X sig_default(SIGSTOP);
  1150. X
  1151. X sig_sethandler(SIGTERM,finish); sig_handle(SIGTERM);
  1152. X sig_sethandler(SIGINT,finish); sig_handle(SIGINT);
  1153. X sig_sethandler(SIGQUIT,finish); sig_handle(SIGQUIT);
  1154. X sig_sethandler(SIGHUP,finish); sig_handle(SIGHUP);
  1155. X sig_sethandler(SIGUSR1,finish); sig_handle(SIGUSR1); /* disconnect */
  1156. X
  1157. X sig_sethandler(SIGCONT,sig_cont); sig_handle(SIGCONT);
  1158. X
  1159. X sig_sethandler(SIGUSR2,sig_usr2); sig_handle(SIGUSR2);
  1160. X
  1161. X for (;;)
  1162. X  {
  1163. X   ch = '0';
  1164. X   if (flagcont)
  1165. X    {
  1166. X     flagcont = 0;
  1167. X     if (tty_modifymodes(fdtty,&tmochartty,&tmotty) == -1)
  1168. X       ; /* XXX: impossible, but what if it happens? */
  1169. X     (void) kill(masterpid,SIGUSR1); /* not CONT---see master.c's sig_cont() */
  1170. X    }
  1171. X#ifdef NO_FDPASSING
  1172. X   if (flagmaster == 2)
  1173. X    {
  1174. X     static fd_set rfds;
  1175. X     static fd_set wfds;
  1176. X     static int r;
  1177. X     static int w;
  1178. X     static char foobuf[OUTBUFSIZE];
  1179. X     int fdnum;
  1180. X     static char *s;
  1181. X
  1182. X     fdnum = fd; if (fdin > fdnum) fdnum = fdin;
  1183. X     if (pi[0] > fdnum) fdnum = pi[0]; fdnum++;
  1184. X
  1185. X     FD_ZERO(&rfds);
  1186. X     FD_ZERO(&wfds);
  1187. X     FD_SET(fd,&rfds);
  1188. X     FD_SET(fdin,&rfds);
  1189. X     FD_SET(pi[0],&rfds);
  1190. X
  1191. X     r = select(fdnum,&rfds,&wfds,(fd_set *) 0,(struct timeval *) 0);
  1192. X     if (r > 0)
  1193. X      {
  1194. X       if (FD_ISSET(fd,&rfds))
  1195. X    {
  1196. X     if ((r = read(fd,foobuf,OUTBUFSIZE)) == -1)
  1197. X       deatherrp(11,"pty: fatal: socket read error");
  1198. X     s = foobuf;
  1199. X     /* XXX: r can't be zero, but what if it is? */
  1200. X     while (r)
  1201. X      {
  1202. X       if ((w = write(fdout,s,r)) == -1)
  1203. X         deatherrp(14,"pty: fatal: output write error");
  1204. X       r -= w; s += w;
  1205. X      }
  1206. X    }
  1207. X       if (FD_ISSET(fdin,&rfds))
  1208. X    {
  1209. X     if ((r = read(fdin,foobuf,OUTBUFSIZE)) == -1)
  1210. X       deatherrp(13,"pty: fatal: input read error");
  1211. X     s = foobuf;
  1212. X     /* XXX: What if r is zero? Can't pass EOF, grrrr */
  1213. X     while (r)
  1214. X      {
  1215. X       if ((w = write(fd,s,r)) == -1)
  1216. X         deatherrp(12,"pty: fatal: socket write error");
  1217. X       r -= w; s += w;
  1218. X      }
  1219. X    }
  1220. X       if (FD_ISSET(pi[0],&rfds))
  1221. X     (void) read(pi[0],&ch,1);
  1222. X      }
  1223. X    }
  1224. X   else
  1225. X     (void) read(pi[0],&ch,1);
  1226. X#else
  1227. X   (void) read(pi[0],&ch,1);
  1228. X#endif
  1229. X   if ((ch == '.') || (ch == ','))
  1230. X    {
  1231. X     if (fd != -1)
  1232. X       (void) close(fd);
  1233. X     if (flagmaster)
  1234. X      {
  1235. X       if (kill(masterpid,SIGTERM) == -1)
  1236. X     flagmaster = 0; /* XXX */
  1237. X
  1238. X       if (fdpass != -1)
  1239. X     (void) write(fdpass,".",1);
  1240. X    
  1241. X       while (flagmaster)
  1242. X         ;
  1243. X       while (ch != '.')
  1244. X         (void) read(pi[0],&ch,1);
  1245. X      }
  1246. X
  1247. X     /* We don't test at this point whether the killing signal was a HUP. */
  1248. X     /* This means that hanging up on a reconnecting sigler won't stop */
  1249. X     /* the reconnect; instead, the new session will be instantly hung */
  1250. X     /* up. The USR1 used for a manual disconnect could be HUP for this */
  1251. X     /* reason. */
  1252. X     if (flagsession
  1253. X       &&((fd = open(path,O_RDONLY)) != -1)
  1254. X       &&(read(fd,fnsty,sizeof(DEVSTY) - 1) > 0))
  1255. X      {
  1256. X       warnerr2("pty: reconnecting to %s\r\n",fnsty);
  1257. X       (void) close(fd);
  1258. X       (void) unlink(path);
  1259. X       if ((fd = pty_writesock(fnsty)) == -1)
  1260. X     warnerr2("pty: reconnect failed: cannot talk to %s\r\n",fnsty);
  1261. X       else
  1262. X    {
  1263. X     if ((pty_getch(fd,&ch) != -1) && (ch == 'p'))
  1264. X       if (pty_putgetint(fd,'p',&masterpid) != -1)
  1265. X         do
  1266. X          {
  1267. X#ifdef NO_FDPASSING
  1268. X               if (fdtty != -1)
  1269. X        {
  1270. X                 if (!(ttyn = real_ttyname(fdtty))) break;
  1271. X             /* XXX: Should we NXCL here? */
  1272. X             (void) strncpy(fntty,ttyn,TTYNAMELEN - 1);
  1273. X                 if (pty_sendstr(fd,'s',fntty) == -1) break;
  1274. X             if (flagverbose)
  1275. X           warnerr2("pty: sent parent tty %s\r\n",fntty);
  1276. X        }
  1277. X#else
  1278. X           if (fdtty != -1)
  1279. X        {
  1280. X                 if (!(ttyn = real_ttyname(fdtty))) break;
  1281. X             /* XXX: Should we NXCL here? */
  1282. X             (void) strncpy(fntty,ttyn,TTYNAMELEN - 1);
  1283. X                 if (pty_sendstr(fd,'s',fntty) == -1) break;
  1284. X             if (flagverbose)
  1285. X             warnerr2("pty: sent parent tty %s\r\n",fntty);
  1286. X             /* We shouldn't have to send the parent tty name, */
  1287. X             /* but passing the fd alone doesn't set the control */
  1288. X             /* terminal of the receiver (grrrr), and a detached */
  1289. X             /* process effectively has no pgrp. Aargh. */
  1290. X        }
  1291. X
  1292. X           if (fdpass == -1)
  1293. X        {
  1294. X             if (pty_sendfd(fd,'0',&fdin) == -1) break;
  1295. X             if (pty_sendfd(fd,'1',&fdout) == -1) break;
  1296. X        }
  1297. X           else
  1298. X         if (pty_sendfd(fd,'f',&fdpass) == -1) break;
  1299. X           if (fdtty != -1)
  1300. X         if (pty_sendfd(fd,'t',&fdtty) == -1) break;
  1301. X#endif
  1302. X           if (pty_sendint(fd,'p',&pid) == -1) break;
  1303. X           if (pty_sendint(fd,'g',&pgrp) == -1) break;
  1304. X           if (pty_sendint(fd,'j',&flagjobctrl) == -1) break;
  1305. X           if (fdtty != -1)
  1306. X        {
  1307. X         if (pty_sendtty(fd,'c',&tmochartty) == -1) break;
  1308. X         if (pty_sendtty(fd,'n',&tmotty) == -1) break;
  1309. X        }
  1310. X           if (pty_putch(fd," ") == -1) break;
  1311. X#ifdef NO_FDPASSING
  1312. X           flagmaster = 2; /* Success, but pain coming up. */
  1313. X#else
  1314. X           flagmaster = 1; /* Successfully reconnected! */
  1315. X#endif
  1316. X          }
  1317. X         while(0);
  1318. X     if (flagmaster < 2)
  1319. X      {
  1320. X           (void) close(fd);
  1321. X       fd = -1;
  1322. X      }
  1323. X    }
  1324. X       if (flagmaster)
  1325. X    {
  1326. X     /* remake path for new pty */
  1327. X         (void) sprintf(path,"sig.%s",fnsty + sizeof(DEVSTY) - 3);
  1328. X         (void) unlink(path);
  1329. X     warnerr2("pty: successfully reconnected to %s\r\n",fnsty);
  1330. X    }
  1331. X       else
  1332. X     warnerr2("pty: reconnect to %s failed\r\n",fnsty);
  1333. X      }
  1334. X     if (!flagmaster)
  1335. X      {
  1336. X       if (tty_modifymodes(fdtty,&tmotty,&tmochartty) == -1)
  1337. X         warnerr2("%s","pty: can't restore tty modes\n"); /*XXX*/
  1338. X       fatal(0);
  1339. X       /*NOTREACHED*/
  1340. X      }
  1341. X    }
  1342. X  }
  1343. X}
  1344. END_OF_FILE
  1345.   if test 8120 -ne `wc -c <'sigler.c'`; then
  1346.     echo shar: \"'sigler.c'\" unpacked with wrong size!
  1347.   fi
  1348.   # end of 'sigler.c'
  1349. fi
  1350. if test -f 'sock.c' -a "${1}" != "-c" ; then 
  1351.   echo shar: Will not clobber existing file \"'sock.c'\"
  1352. else
  1353.   echo shar: Extracting \"'sock.c'\" \(5474 characters\)
  1354.   sed "s/^X//" >'sock.c' <<'END_OF_FILE'
  1355. X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
  1356. X
  1357. X#include "config.h"
  1358. X#include <sys/types.h>
  1359. X#include <sys/time.h>
  1360. X#ifndef NO_UNIXSOCKS
  1361. X#include <sys/socket.h>
  1362. X#include <sys/un.h>
  1363. X#ifndef NO_FDPASSING
  1364. X#include <sys/uio.h>
  1365. X#endif
  1366. X#include <stdio.h>
  1367. X#include <strings.h>
  1368. X#endif
  1369. X#include "sock.h"
  1370. X#include "tty.h"
  1371. X#include "err.h"
  1372. X
  1373. Xstatic int bufwrite(fd,buf,num)
  1374. Xint fd;
  1375. Xchar *buf;
  1376. Xint num;
  1377. X{
  1378. X int r;
  1379. X
  1380. X do
  1381. X  {
  1382. X   r = write(fd,buf,num);
  1383. X   if (r > 0)
  1384. X    {
  1385. X     buf += r;
  1386. X     num -= r;
  1387. X    }
  1388. X  }
  1389. X while ((num > 0) && ((r != -1) || (errno == EINTR)));
  1390. X return (r >= 0) ? 0 : -1;
  1391. X}
  1392. X
  1393. Xstatic int bufread(fd,buf,num)
  1394. Xint fd;
  1395. Xchar *buf;
  1396. Xint num;
  1397. X{
  1398. X int r;
  1399. X
  1400. X do
  1401. X  {
  1402. X   r = read(fd,buf,num);
  1403. X   if (r > 0)
  1404. X    {
  1405. X     buf += r;
  1406. X     num -= r;
  1407. X    }
  1408. X  }
  1409. X while ((num > 0) && ((r != -1) || (errno == EINTR)));
  1410. X /* Note that we ignore EOF. */
  1411. X return (r >= 0) ? 0 : -1;
  1412. X}
  1413. X
  1414. Xint pty_readsock(line,path)
  1415. Xchar *line;
  1416. Xchar *path;
  1417. X{
  1418. X#ifdef NO_UNIXSOCKS
  1419. X return -1;
  1420. X#else
  1421. X int s;
  1422. X struct sockaddr_un sa;
  1423. X
  1424. X if ((s = socket(AF_UNIX,SOCK_STREAM,0)) == -1)
  1425. X   return -1;
  1426. X sa.sun_family = AF_UNIX;
  1427. X (void) sprintf(sa.sun_path,"re.%s",line + sizeof(DEVSTY) - 3);
  1428. X (void) strcpy(path,sa.sun_path);
  1429. X (void) unlink(sa.sun_path);
  1430. X if (bind(s,(struct sockaddr *) &sa,strlen(sa.sun_path) + 2) == -1)
  1431. X   return -1;
  1432. X if (listen(s,5) == -1)
  1433. X   return -1;
  1434. X return s;
  1435. X#endif
  1436. X}
  1437. X
  1438. Xint pty_writesock(line)
  1439. Xchar *line;
  1440. X{
  1441. X#ifdef NO_UNIXSOCKS
  1442. X return -1;
  1443. X#else
  1444. X int s;
  1445. X struct sockaddr_un sa;
  1446. X
  1447. X if ((s = socket(AF_UNIX,SOCK_STREAM,0)) == -1)
  1448. X   return -1;
  1449. X sa.sun_family = AF_UNIX;
  1450. X (void) sprintf(sa.sun_path,"re.%s",line + sizeof(DEVSTY) - 3);
  1451. X if (connect(s,(struct sockaddr *) &sa,strlen(sa.sun_path) + 2) == -1)
  1452. X   return -1;
  1453. X (void) unlink(sa.sun_path);
  1454. X return s;
  1455. X#endif
  1456. X}
  1457. X
  1458. Xint pty_acceptsock(fd)
  1459. Xint fd;
  1460. X{
  1461. X#ifdef NO_UNIXSOCKS
  1462. X return -1;
  1463. X#else
  1464. X struct sockaddr_un sa;
  1465. X int salen = sizeof(sa);
  1466. X
  1467. X return accept(fd,(struct sockaddr *) &sa,&salen);
  1468. X#endif
  1469. X}
  1470. X
  1471. Xint pty_putgetonefd(fd,fp)
  1472. Xint fd;
  1473. Xint *fp;
  1474. X{
  1475. X#ifdef NO_FDPASSING
  1476. X return -1;
  1477. X#else
  1478. X struct msghdr msg[2];
  1479. X int acc[5];
  1480. X struct iovec i[2];
  1481. X
  1482. X msg[0].msg_name = 0;
  1483. X msg[0].msg_namelen = 0;
  1484. X msg[0].msg_iov = &i[0]; /* grrrr */
  1485. X msg[0].msg_iovlen = 0;
  1486. X msg[0].msg_accrights = (caddr_t) acc;
  1487. X msg[0].msg_accrightslen = 5 * sizeof(int);
  1488. X#ifdef USLEEP
  1489. X (void) usleep((unsigned) 100000);
  1490. X#else
  1491. X (void) sleep(1); /* XXX: work around fd passing bug */
  1492. X#endif
  1493. X if (recvmsg(fd,msg,0) == -1)
  1494. X   return -1;
  1495. X if (msg[0].msg_accrightslen != sizeof(int))
  1496. X   return -1;
  1497. X if (*fp != -1)
  1498. X   (void) close(*fp);
  1499. X *fp = acc[0]; /* yay! we've passed a file descriptor! */
  1500. X return 0;
  1501. X#endif
  1502. X}
  1503. X
  1504. Xint pty_putgetfd(fd,ch,fp)
  1505. Xint fd;
  1506. Xchar ch;
  1507. Xint *fp;
  1508. X{
  1509. X#ifdef NO_FDPASSING
  1510. X return -1;
  1511. X#else
  1512. X if (bufwrite(fd,&ch,1) < 0)
  1513. X   return -1;
  1514. X if (pty_putgetonefd(fd,fp) < 0)
  1515. X   return -1;
  1516. X if (bufwrite(fd,".",1) < 0)
  1517. X   return -1;
  1518. X return 0;
  1519. X#endif
  1520. X}
  1521. X
  1522. Xint pty_putgetint(fd,ch,ip)
  1523. Xint fd;
  1524. Xchar ch;
  1525. Xint *ip;
  1526. X{
  1527. X if (bufwrite(fd,&ch,1) < 0)
  1528. X   return -1;
  1529. X if (bufread(fd,(char *) ip,sizeof(int)) < 0)
  1530. X   return -1;
  1531. X if (bufwrite(fd,".",1) < 0)
  1532. X   return -1;
  1533. X return 0;
  1534. X}
  1535. X
  1536. Xint pty_putgetstr(fd,ch,str)
  1537. Xint fd;
  1538. Xchar ch;
  1539. Xchar str[TTYNAMELEN];
  1540. X{
  1541. X if (bufwrite(fd,&ch,1) < 0)
  1542. X   return -1;
  1543. X if (bufread(fd,str,TTYNAMELEN) < 0)
  1544. X   return -1;
  1545. X if (bufwrite(fd,".",1) < 0)
  1546. X   return -1;
  1547. X return 0;
  1548. X}
  1549. X
  1550. Xint pty_putgettty(fd,ch,tmo)
  1551. Xint fd;
  1552. Xchar ch;
  1553. Xstruct ttymodes *tmo;
  1554. X{
  1555. X if (bufwrite(fd,&ch,1) < 0)
  1556. X   return -1;
  1557. X if (bufread(fd,(char *) tmo,sizeof(struct ttymodes)) < 0)
  1558. X   return -1;
  1559. X if (bufwrite(fd,".",1) < 0)
  1560. X   return -1;
  1561. X return 0;
  1562. X}
  1563. X
  1564. Xint pty_sendonefd(fd,fp)
  1565. Xint fd;
  1566. Xint *fp;
  1567. X{
  1568. X#ifdef NO_FDPASSING
  1569. X return -1;
  1570. X#else
  1571. X struct msghdr msg[2];
  1572. X int acc[5]; /* or just 5? or just 1? who cares */
  1573. X struct iovec i[2];
  1574. X
  1575. X msg[0].msg_name = 0;
  1576. X msg[0].msg_namelen = 0;
  1577. X msg[0].msg_iov = i; /* grrrr */
  1578. X msg[0].msg_iovlen = 0;
  1579. X msg[0].msg_accrights = (caddr_t) acc;
  1580. X msg[0].msg_accrightslen = sizeof(int);
  1581. X acc[0] = *fp;
  1582. X if (sendmsg(fd,&msg[0],0) == -1)
  1583. X   return -1;
  1584. X /* yay! we've passed a file descriptor! */
  1585. X return 0;
  1586. X#endif
  1587. X}
  1588. X
  1589. Xint pty_sendfd(fd,ch,fp)
  1590. Xint fd;
  1591. Xchar ch;
  1592. Xint *fp;
  1593. X{
  1594. X#ifdef NO_FDPASSING
  1595. X return -1;
  1596. X#else
  1597. X if (bufwrite(fd,&ch,1) < 0)
  1598. X   return -1;
  1599. X if (bufread(fd,&ch,1) < 0)
  1600. X   return -1;
  1601. X if (ch == ' ')
  1602. X   return 1;
  1603. X if (pty_sendonefd(fd,fp) < 0)
  1604. X   return -1;
  1605. X if (bufread(fd,&ch,1) < 0)
  1606. X   return -1;
  1607. X if (ch != '.')
  1608. X   return 1;
  1609. X return 0;
  1610. X#endif
  1611. X}
  1612. X
  1613. Xint pty_sendint(fd,ch,ip)
  1614. Xint fd;
  1615. Xchar ch;
  1616. Xint *ip;
  1617. X{
  1618. X if (bufwrite(fd,&ch,1) < 0)
  1619. X   return -1;
  1620. X if (bufread(fd,&ch,1) < 0)
  1621. X   return -1;
  1622. X if (ch == ' ')
  1623. X   return 1;
  1624. X if (bufwrite(fd,(char *) ip,sizeof(int)) < 0)
  1625. X   return -1;
  1626. X if (bufread(fd,&ch,1) < 0)
  1627. X   return -1;
  1628. X if (ch != '.')
  1629. X   return 1;
  1630. X return 0;
  1631. X}
  1632. X
  1633. Xint pty_sendstr(fd,ch,str)
  1634. Xint fd;
  1635. Xchar ch;
  1636. Xchar str[TTYNAMELEN];
  1637. X{
  1638. X if (bufwrite(fd,&ch,1) < 0)
  1639. X   return -1;
  1640. X if (bufread(fd,&ch,1) < 0)
  1641. X   return -1;
  1642. X if (ch == ' ')
  1643. X   return 1;
  1644. X if (bufwrite(fd,str,TTYNAMELEN) < 0)
  1645. X   return -1;
  1646. X if (bufread(fd,&ch,1) < 0)
  1647. X   return -1;
  1648. X if (ch != '.')
  1649. X   return 1;
  1650. X return 0;
  1651. X}
  1652. X
  1653. Xint pty_sendtty(fd,ch,tmo)
  1654. Xint fd;
  1655. Xchar ch;
  1656. Xstruct ttymodes *tmo;
  1657. X{
  1658. X if (bufwrite(fd,&ch,1) < 0)
  1659. X   return -1;
  1660. X if (bufread(fd,&ch,1) < 0)
  1661. X   return -1;
  1662. X if (ch == ' ')
  1663. X   return 1;
  1664. X if (bufwrite(fd,(char *) tmo,sizeof(struct ttymodes)) < 0)
  1665. X   return -1;
  1666. X if (bufread(fd,&ch,1) < 0)
  1667. X   return -1;
  1668. X if (ch != '.')
  1669. X   return 1;
  1670. X return 0;
  1671. X}
  1672. X
  1673. Xint pty_putch(fd,ch)
  1674. Xint fd;
  1675. Xchar *ch;
  1676. X{
  1677. X return bufwrite(fd,ch,1);
  1678. X}
  1679. X
  1680. Xint pty_getch(fd,ch)
  1681. Xint fd;
  1682. Xchar *ch;
  1683. X{
  1684. X return bufread(fd,ch,1);
  1685. X}
  1686. END_OF_FILE
  1687.   if test 5474 -ne `wc -c <'sock.c'`; then
  1688.     echo shar: \"'sock.c'\" unpacked with wrong size!
  1689.   fi
  1690.   # end of 'sock.c'
  1691. fi
  1692. if test -f 'tty.c' -a "${1}" != "-c" ; then 
  1693.   echo shar: Will not clobber existing file \"'tty.c'\"
  1694. else
  1695.   echo shar: Extracting \"'tty.c'\" \(8009 characters\)
  1696.   sed "s/^X//" >'tty.c' <<'END_OF_FILE'
  1697. X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
  1698. X
  1699. X#include "config.h"
  1700. X#include <sys/ioctl.h>
  1701. X#include "file.h"
  1702. X#include "err.h"
  1703. X#include "tty.h"
  1704. X
  1705. X#define generic GENERIC *
  1706. X
  1707. Xstatic int ioc(fd,req,arg) /* non-interruptable ioctl */
  1708. Xint fd;
  1709. Xunsigned long req;
  1710. Xgeneric arg;
  1711. X{
  1712. X int result;
  1713. X
  1714. X do
  1715. X   result = ioctl(fd,req,(char *) arg);
  1716. X while ((result == -1) && (errno == EINTR));
  1717. X return result;
  1718. X}
  1719. X
  1720. Xint tty_getctrl()
  1721. X{
  1722. X int fd;
  1723. X int dummy;
  1724. X
  1725. X#define ISTTY(f) (ioc(f,(unsigned long) TIOCGPGRP,(generic) &dummy) == 0)
  1726. X
  1727. X if (ISTTY(3))
  1728. X   return 3;
  1729. X if (((fd = open("/dev/tty",O_RDWR)) != -1) && ISTTY(fd))
  1730. X   return fd;
  1731. X if (((fd = dup(0)) != -1) && ISTTY(fd))
  1732. X   return fd;
  1733. X if (((fd = dup(1)) != -1) && ISTTY(fd))
  1734. X   return fd;
  1735. X return -1;
  1736. X}
  1737. X
  1738. Xtty_setexcl(fd)
  1739. Xint fd;
  1740. X{
  1741. X return ioc(fd,(unsigned long) TIOCEXCL,(generic) 0);
  1742. X /* setting exclusive use is a bit unusual but it works */
  1743. X /* opening /dev/tty should still be allowed, though */
  1744. X}
  1745. X
  1746. Xtty_setpgrp(fd,pgrp)
  1747. Xint fd;
  1748. Xint pgrp;
  1749. X{
  1750. X return ioc(fd,(unsigned long) TIOCSPGRP,(generic) &pgrp);
  1751. X}
  1752. X
  1753. Xtty_dissoc(fd)
  1754. Xint fd;
  1755. X{
  1756. X return ioc(fd,(unsigned long) TIOCNOTTY,(generic) 0);
  1757. X}
  1758. X
  1759. Xtty_getmodes(fd,tmo)
  1760. Xint fd;
  1761. Xstruct ttymodes *tmo;
  1762. X{
  1763. X if (ioc(fd,(unsigned long) TIOCGETD,(generic) &(tmo->di)) == -1) return -1;
  1764. X if (ioc(fd,(unsigned long) TIOCGETP,(generic) &(tmo->sg)) == -1) return -1;
  1765. X if (ioc(fd,(unsigned long) TIOCGETC,(generic) &(tmo->tc)) == -1) return -1;
  1766. X if (ioc(fd,(unsigned long) TIOCLGET,(generic) &(tmo->lb)) == -1) return -1;
  1767. X if (ioc(fd,(unsigned long) TIOCGLTC,(generic) &(tmo->lt)) == -1) return -1;
  1768. X#ifdef TTY_WINDOWS
  1769. X if (ioc(fd,(unsigned long) TIOCGWINSZ,(generic) &(tmo->ws)) == -1) return -1;
  1770. X#endif
  1771. X#ifdef TTY_AUXCHARS
  1772. X if (ioc(fd,(unsigned long) TIOCGAUXC,(generic) &(tmo->au)) == -1) return -1;
  1773. X#endif
  1774. X return 0;
  1775. X}
  1776. X
  1777. Xtty_setmodes(fd,tmo)
  1778. Xint fd;
  1779. Xstruct ttymodes *tmo;
  1780. X{
  1781. X if (ioc(fd,(unsigned long) TIOCSETD,(generic) &(tmo->di)) == -1) return -1;
  1782. X if (ioc(fd,(unsigned long) TIOCSETP,(generic) &(tmo->sg)) == -1) return -1;
  1783. X if (ioc(fd,(unsigned long) TIOCSETC,(generic) &(tmo->tc)) == -1) return -1;
  1784. X if (ioc(fd,(unsigned long) TIOCLSET,(generic) &(tmo->lb)) == -1) return -1;
  1785. X if (ioc(fd,(unsigned long) TIOCSLTC,(generic) &(tmo->lt)) == -1) return -1;
  1786. X#ifdef TTY_WINDOWS
  1787. X if (ioc(fd,(unsigned long) TIOCSWINSZ,(generic) &(tmo->ws)) == -1) return -1;
  1788. X#endif
  1789. X#ifdef TTY_AUXCHARS
  1790. X if (ioc(fd,(unsigned long) TIOCSAUXC,(generic) &(tmo->au)) == -1) return -1;
  1791. X#endif
  1792. X return 0;
  1793. X}
  1794. X
  1795. Xtty_modifymodes(fd,tmonew,tmoold)
  1796. Xint fd;
  1797. Xstruct ttymodes *tmonew;
  1798. Xstruct ttymodes *tmoold;
  1799. X{
  1800. X if (tmonew->di != tmoold->di)
  1801. X   if (ioc(fd,(unsigned long) TIOCSETD,(generic) &(tmonew->di)) == -1) return -1;
  1802. X if ((tmonew->sg.sg_flags != tmoold->sg.sg_flags)
  1803. X   ||(tmonew->sg.sg_ispeed != tmoold->sg.sg_ispeed)
  1804. X   ||(tmonew->sg.sg_ospeed != tmoold->sg.sg_ospeed)
  1805. X   ||(tmonew->sg.sg_erase != tmoold->sg.sg_erase)
  1806. X   ||(tmonew->sg.sg_kill != tmoold->sg.sg_kill))
  1807. X   if (ioc(fd,(unsigned long) TIOCSETP,(generic) &(tmonew->sg)) == -1) return -1;
  1808. X if ((tmonew->tc.t_intrc != tmoold->tc.t_intrc)
  1809. X   ||(tmonew->tc.t_quitc != tmoold->tc.t_quitc)
  1810. X   ||(tmonew->tc.t_startc != tmoold->tc.t_startc)
  1811. X   ||(tmonew->tc.t_stopc != tmoold->tc.t_stopc)
  1812. X   ||(tmonew->tc.t_eofc != tmoold->tc.t_eofc)
  1813. X   ||(tmonew->tc.t_brkc != tmoold->tc.t_brkc))
  1814. X   if (ioc(fd,(unsigned long) TIOCSETC,(generic) &(tmonew->tc)) == -1) return -1;
  1815. X if (tmonew->lb != tmoold->lb)
  1816. X   if (ioc(fd,(unsigned long) TIOCLSET,(generic) &(tmonew->lb)) == -1) return -1;
  1817. X if ((tmonew->lt.t_suspc != tmoold->lt.t_suspc)
  1818. X   ||(tmonew->lt.t_dsuspc != tmoold->lt.t_dsuspc)
  1819. X   ||(tmonew->lt.t_rprntc != tmoold->lt.t_rprntc)
  1820. X   ||(tmonew->lt.t_flushc != tmoold->lt.t_flushc)
  1821. X   ||(tmonew->lt.t_werasc != tmoold->lt.t_werasc)
  1822. X   ||(tmonew->lt.t_lnextc != tmoold->lt.t_lnextc))
  1823. X   if (ioc(fd,(unsigned long) TIOCSLTC,(generic) &(tmonew->lt)) == -1) return -1;
  1824. X#ifdef TTY_WINDOWS
  1825. X if ((tmonew->ws.ws_xpixel != tmoold->ws.ws_xpixel)
  1826. X   ||(tmonew->ws.ws_ypixel != tmoold->ws.ws_ypixel)
  1827. X   ||(tmonew->ws.ws_row != tmoold->ws.ws_row)
  1828. X   ||(tmonew->ws.ws_col != tmoold->ws.ws_col))
  1829. X   if (ioc(fd,(unsigned long)TIOCSWINSZ,(generic)&(tmonew->ws))==-1) return -1;
  1830. X#endif
  1831. X#ifdef TTY_AUXCHARS
  1832. X if ((tmonew->au.t_usemap != tmoold->au.t_usemap)
  1833. X   ||(tmonew->au.t_usest != tmoold->au.t_usest))
  1834. X   if (ioc(fd,(unsigned long)TIOCSAUXC,(generic)&(tmonew->au))==-1) return -1;
  1835. X#endif
  1836. X return 0;
  1837. X}
  1838. X
  1839. X/* XXX: Should use copy() for this. */
  1840. Xvoid tty_copymodes(tmonew,tmoold)
  1841. Xstruct ttymodes *tmonew;
  1842. Xstruct ttymodes *tmoold;
  1843. X{
  1844. X tmonew->di = tmoold->di;
  1845. X tmonew->sg.sg_ispeed = tmoold->sg.sg_ispeed;
  1846. X tmonew->sg.sg_ospeed = tmoold->sg.sg_ospeed;
  1847. X tmonew->sg.sg_erase = tmoold->sg.sg_erase;
  1848. X tmonew->sg.sg_kill = tmoold->sg.sg_kill;
  1849. X tmonew->sg.sg_flags = tmoold->sg.sg_flags;
  1850. X tmonew->tc.t_intrc = tmoold->tc.t_intrc;
  1851. X tmonew->tc.t_quitc = tmoold->tc.t_quitc;
  1852. X tmonew->tc.t_startc = tmoold->tc.t_startc;
  1853. X tmonew->tc.t_stopc = tmoold->tc.t_stopc;
  1854. X tmonew->tc.t_eofc = tmoold->tc.t_eofc;
  1855. X tmonew->tc.t_brkc = tmoold->tc.t_brkc;
  1856. X tmonew->lb = tmoold->lb;
  1857. X tmonew->lt.t_suspc = tmoold->lt.t_suspc;
  1858. X tmonew->lt.t_dsuspc = tmoold->lt.t_dsuspc;
  1859. X tmonew->lt.t_rprntc = tmoold->lt.t_rprntc;
  1860. X tmonew->lt.t_flushc = tmoold->lt.t_flushc;
  1861. X tmonew->lt.t_werasc = tmoold->lt.t_werasc;
  1862. X tmonew->lt.t_lnextc = tmoold->lt.t_lnextc;
  1863. X#ifdef TTY_WINDOWS
  1864. X tmonew->ws.ws_xpixel = tmoold->ws.ws_xpixel;
  1865. X tmonew->ws.ws_ypixel = tmoold->ws.ws_ypixel;
  1866. X tmonew->ws.ws_row = tmoold->ws.ws_row;
  1867. X tmonew->ws.ws_col = tmoold->ws.ws_col;
  1868. X#endif
  1869. X#ifdef TTY_AUXCHARS
  1870. X tmonew->au.t_usest = tmoold->au.t_usest;
  1871. X tmonew->au.t_usemap = tmoold->au.t_usemap;
  1872. X#endif
  1873. X}
  1874. X
  1875. Xvoid tty_copywin(tmonew,tmoold)
  1876. Xstruct ttymodes *tmonew;
  1877. Xstruct ttymodes *tmoold;
  1878. X{
  1879. X ;
  1880. X#ifdef TTY_WINDOWS
  1881. X tmonew->ws.ws_xpixel = tmoold->ws.ws_xpixel;
  1882. X tmonew->ws.ws_ypixel = tmoold->ws.ws_ypixel;
  1883. X tmonew->ws.ws_row = tmoold->ws.ws_row;
  1884. X tmonew->ws.ws_col = tmoold->ws.ws_col;
  1885. X#endif
  1886. X}
  1887. X
  1888. Xvoid tty_charmode(tmo)
  1889. Xstruct ttymodes *tmo;
  1890. X{
  1891. X tty_mungemodes(tmo,3,0,2,0,3,0);
  1892. X}
  1893. X
  1894. Xvoid tty_mungemodes(tmo,cbreak,new,echo,crmod,raw,crt)
  1895. Xstruct ttymodes *tmo;
  1896. Xint cbreak;
  1897. Xint new;
  1898. Xint echo;
  1899. Xint crmod;
  1900. Xint raw;
  1901. Xint crt;
  1902. X{
  1903. X if (new >= 2)
  1904. X   tmo->di = ((new == 3) ? NTTYDISC : OTTYDISC);
  1905. X if (crmod >= 2)
  1906. X   tmo->sg.sg_flags = (tmo->sg.sg_flags & ~CRMOD) | (CRMOD * (crmod == 3));
  1907. X if (echo >= 2)
  1908. X   tmo->sg.sg_flags = (tmo->sg.sg_flags & ~ECHO) | (ECHO * (echo == 3));
  1909. X if (raw >= 2)
  1910. X   tmo->sg.sg_flags = (tmo->sg.sg_flags & ~RAW) | (RAW * (raw == 3));
  1911. X if (cbreak >= 2)
  1912. X   tmo->sg.sg_flags = (tmo->sg.sg_flags & ~CBREAK) | (CBREAK * (cbreak == 3));
  1913. X if (crt >= 2)
  1914. X   tmo->lb = (tmo->lb & ~(CRTBS | CRTERA | CRTKIL | CTLECH))
  1915. X                      | ((CRTBS | CRTERA | CRTKIL | CTLECH) * (crt == 3));
  1916. X}
  1917. X
  1918. Xvoid tty_initmodes(tmo,cbreak,new,echo,crmod,raw,crt)
  1919. Xstruct ttymodes *tmo;
  1920. Xint cbreak;
  1921. Xint new;
  1922. Xint echo;
  1923. Xint crmod;
  1924. Xint raw;
  1925. Xint crt;
  1926. X{
  1927. X /* Here we specify Ye Standard BSD Terminal Settings. */
  1928. X
  1929. X tmo->di = ((new % 2) ? NTTYDISC : OTTYDISC);
  1930. X tmo->sg.sg_ispeed = EXTB;
  1931. X tmo->sg.sg_ospeed = EXTB;
  1932. X tmo->sg.sg_erase = 127; /* del */
  1933. X tmo->sg.sg_kill = 21; /* ^U */
  1934. X tmo->sg.sg_flags = EVENP | ODDP | XTABS
  1935. X   | (CRMOD * (crmod % 2)) | (ECHO * (echo % 2))
  1936. X   | (RAW * (raw % 2)) | (CBREAK * (cbreak % 2));
  1937. X tmo->tc.t_intrc = 3; /* ^C */
  1938. X tmo->tc.t_quitc = 28; /* ^\ */
  1939. X tmo->tc.t_startc = 17; /* ^Q */
  1940. X tmo->tc.t_stopc = 19; /* ^S */
  1941. X tmo->tc.t_eofc = 4; /* ^D */
  1942. X tmo->tc.t_brkc = -1; /* undef */
  1943. X tmo->lb = ((CRTBS | CRTERA | CRTKIL | CTLECH) * (crt % 2)) | DECCTQ;
  1944. X tmo->lt.t_suspc = 26; /* ^Z */
  1945. X tmo->lt.t_dsuspc = 25; /* ^Y */
  1946. X tmo->lt.t_rprntc = 18; /* ^R */
  1947. X tmo->lt.t_flushc = 15; /* ^O */
  1948. X tmo->lt.t_werasc = 23; /* ^W */
  1949. X tmo->lt.t_lnextc = 22; /* ^V */
  1950. X#ifdef TTY_WINDOWS
  1951. X tmo->ws.ws_xpixel = 0; /* Or read from TERMCAP? Hmmm */
  1952. X tmo->ws.ws_ypixel = 0;
  1953. X tmo->ws.ws_row = 0;
  1954. X tmo->ws.ws_col = 0;
  1955. X#endif
  1956. X#ifdef TTY_AUXCHARS
  1957. X tmo->au.t_usest = 20; /* ^T */
  1958. X tmo->au.t_usemap = UST_LOAD1 | UST_LOAD5 | UST_LOAD15 | UST_RAWCPU
  1959. X   | UST_UPTIME | UST_PGRP | UST_CHILDS | UST_PCPU | UST_STATE;
  1960. X#endif
  1961. X}
  1962. END_OF_FILE
  1963.   if test 8009 -ne `wc -c <'tty.c'`; then
  1964.     echo shar: \"'tty.c'\" unpacked with wrong size!
  1965.   fi
  1966.   # end of 'tty.c'
  1967. fi
  1968. if test -f 'util/Makefile' -a "${1}" != "-c" ; then 
  1969.   echo shar: Will not clobber existing file \"'util/Makefile'\"
  1970. else
  1971.   echo shar: Extracting \"'util/Makefile'\" \(4818 characters\)
  1972.   sed "s/^X//" >'util/Makefile' <<'END_OF_FILE'
  1973. XCC=cc
  1974. XCCOPTS=-O2 -s
  1975. X
  1976. XNROFF=nroff
  1977. XNROFFOPTS=-man
  1978. X
  1979. X# This Makefile is exceedingly boring. Then again, it's portable.
  1980. X
  1981. Xdefault: all
  1982. X
  1983. Xall: progs mans
  1984. X
  1985. Xprogs: excloff exclon lock tiocsti who u biff mesg tty write wall sessuser sessname sesskill sesslist disconnect reconnect xsessuser xsessname xsesskill xsesslist xdisconnect xreconnect sessutil.o xsessutil.o
  1986. X
  1987. Xmans: excloff.man exclon.man lock.man tiocsti.man who.man u.man biff.man mesg.man tty.man write.man wall.man sessuser.man sessname.man sesskill.man sesslist.man disconnect.man reconnect.man script.man script.tidy.man condom.man sess.man
  1988. X
  1989. Xexcloff: excloff.c Makefile
  1990. X    $(CC) $(CCOPTS) -o excloff excloff.c
  1991. X
  1992. Xexclon: exclon.c Makefile
  1993. X    $(CC) $(CCOPTS) -o exclon exclon.c
  1994. X
  1995. Xlock: lock.c Makefile
  1996. X    $(CC) $(CCOPTS) -o lock lock.c -lcurses -ltermcap
  1997. X
  1998. Xtiocsti: tiocsti.c Makefile
  1999. X    $(CC) $(CCOPTS) -o tiocsti tiocsti.c
  2000. X
  2001. Xwho: who.c Makefile
  2002. X    $(CC) $(CCOPTS) -o who who.c
  2003. X
  2004. Xu: u.c Makefile
  2005. X    $(CC) $(CCOPTS) -o u u.c
  2006. X
  2007. Xtty: tty.c Makefile
  2008. X    $(CC) $(CCOPTS) -o tty tty.c
  2009. X
  2010. Xwrite: write.c Makefile
  2011. X    $(CC) $(CCOPTS) -o write write.c
  2012. X
  2013. Xwall: wall.c Makefile
  2014. X    $(CC) $(CCOPTS) -o wall wall.c
  2015. X
  2016. Xbiff: biff.o sessutil.o Makefile
  2017. X    $(CC) $(CCOPTS) -o biff biff.o sessutil.o
  2018. X
  2019. Xmesg: mesg.o sessutil.o Makefile
  2020. X    $(CC) $(CCOPTS) -o mesg mesg.o sessutil.o
  2021. X
  2022. Xsessuser: sessuser.o sessutil.o Makefile
  2023. X    $(CC) $(CCOPTS) -o sessuser sessuser.o sessutil.o
  2024. X
  2025. Xxsessuser: sessuser.o xsessutil.o Makefile
  2026. X    $(CC) $(CCOPTS) -o xsessuser sessuser.o xsessutil.o
  2027. X
  2028. Xsessname: sessname.o sessutil.o Makefile
  2029. X    $(CC) $(CCOPTS) -o sessname sessname.o sessutil.o
  2030. X
  2031. Xxsessname: sessname.o xsessutil.o Makefile
  2032. X    $(CC) $(CCOPTS) -o xsessname sessname.o xsessutil.o
  2033. X
  2034. Xsesskill: sesskill.o sessutil.o Makefile
  2035. X    $(CC) $(CCOPTS) -o sesskill sesskill.o sessutil.o
  2036. X
  2037. Xxsesskill: sesskill.o xsessutil.o Makefile
  2038. X    $(CC) $(CCOPTS) -o xsesskill sesskill.o xsessutil.o
  2039. X
  2040. Xsesslist: sesslist.o sessutil.o Makefile
  2041. X    $(CC) $(CCOPTS) -o sesslist sesslist.o sessutil.o
  2042. X
  2043. Xxsesslist: sesslist.o xsessutil.o Makefile
  2044. X    $(CC) $(CCOPTS) -o xsesslist sesslist.o xsessutil.o
  2045. X
  2046. Xreconnect: reconnect.o sessutil.o Makefile
  2047. X    $(CC) $(CCOPTS) -o reconnect reconnect.o sessutil.o
  2048. X
  2049. Xxreconnect: reconnect.o xsessutil.o Makefile
  2050. X    $(CC) $(CCOPTS) -o xreconnect reconnect.o xsessutil.o
  2051. X
  2052. Xdisconnect: disconnect.o sessutil.o Makefile
  2053. X    $(CC) $(CCOPTS) -o disconnect disconnect.o sessutil.o
  2054. X
  2055. Xxdisconnect: disconnect.o xsessutil.o Makefile
  2056. X    $(CC) $(CCOPTS) -o xdisconnect disconnect.o xsessutil.o
  2057. X
  2058. Xbiff.o: biff.c sessutil.h Makefile
  2059. X    $(CC) $(CCOPTS) -c biff.c
  2060. X
  2061. Xmesg.o: mesg.c sessutil.h Makefile
  2062. X    $(CC) $(CCOPTS) -c mesg.c
  2063. X
  2064. Xsessuser.o: sessuser.c sessutil.h Makefile
  2065. X    $(CC) $(CCOPTS) -c sessuser.c
  2066. X
  2067. Xsessname.o: sessname.c sessutil.h Makefile
  2068. X    $(CC) $(CCOPTS) -c sessname.c
  2069. X
  2070. Xsesskill.o: sesskill.c sessutil.h Makefile
  2071. X    $(CC) $(CCOPTS) -c sesskill.c
  2072. X
  2073. Xsesslist.o: sesslist.c sessutil.h Makefile
  2074. X    $(CC) $(CCOPTS) -c sesslist.c
  2075. X
  2076. Xdisconnect.o: disconnect.c sessutil.h Makefile
  2077. X    $(CC) $(CCOPTS) -c disconnect.c
  2078. X
  2079. Xreconnect.o: reconnect.c sessutil.h Makefile
  2080. X    $(CC) $(CCOPTS) -c reconnect.c
  2081. X
  2082. Xxsessutil.o: xsessutil.c sessutil.h Makefile
  2083. X    $(CC) $(CCOPTS) -c xsessutil.c
  2084. X
  2085. Xsessutil.o: sessutil.c sessutil.h Makefile
  2086. X    $(CC) $(CCOPTS) -c sessutil.c
  2087. X
  2088. Xexcloff.man: excloff.1 Makefile
  2089. X    $(NROFF) $(NROFFOPTS) < excloff.1 > excloff.man
  2090. X
  2091. Xexclon.man: exclon.1 Makefile
  2092. X    $(NROFF) $(NROFFOPTS) < exclon.1 > exclon.man
  2093. X
  2094. Xlock.man: lock.1 Makefile
  2095. X    $(NROFF) $(NROFFOPTS) < lock.1 > lock.man
  2096. X
  2097. Xtiocsti.man: tiocsti.1 Makefile
  2098. X    $(NROFF) $(NROFFOPTS) < tiocsti.1 > tiocsti.man
  2099. X
  2100. Xwho.man: who.1 Makefile
  2101. X    $(NROFF) $(NROFFOPTS) < who.1 > who.man
  2102. X
  2103. Xbiff.man: biff.1 Makefile
  2104. X    $(NROFF) $(NROFFOPTS) < biff.1 > biff.man
  2105. X
  2106. Xmesg.man: mesg.1 Makefile
  2107. X    $(NROFF) $(NROFFOPTS) < mesg.1 > mesg.man
  2108. X
  2109. Xu.man: u.1 Makefile
  2110. X    $(NROFF) $(NROFFOPTS) < u.1 > u.man
  2111. X
  2112. Xtty.man: tty.1 Makefile
  2113. X    $(NROFF) $(NROFFOPTS) < tty.1 > tty.man
  2114. X
  2115. Xwrite.man: write.1 Makefile
  2116. X    $(NROFF) $(NROFFOPTS) < write.1 > write.man
  2117. X
  2118. Xwall.man: wall.1 Makefile
  2119. X    $(NROFF) $(NROFFOPTS) < wall.1 > wall.man
  2120. X
  2121. Xsess.man: sess.1 Makefile
  2122. X    $(NROFF) $(NROFFOPTS) < sess.1 > sess.man
  2123. X
  2124. Xsessuser.man: sessuser.1 Makefile
  2125. X    $(NROFF) $(NROFFOPTS) < sessuser.1 > sessuser.man
  2126. X
  2127. Xsessname.man: sessname.1 Makefile
  2128. X    $(NROFF) $(NROFFOPTS) < sessname.1 > sessname.man
  2129. X
  2130. Xsesskill.man: sesskill.1 Makefile
  2131. X    $(NROFF) $(NROFFOPTS) < sesskill.1 > sesskill.man
  2132. X
  2133. Xsesslist.man: sesslist.1 Makefile
  2134. X    $(NROFF) $(NROFFOPTS) < sesslist.1 > sesslist.man
  2135. X
  2136. Xcondom.man: condom.1 Makefile
  2137. X    $(NROFF) $(NROFFOPTS) < condom.1 > condom.man
  2138. X
  2139. Xscript.man: script.1 Makefile
  2140. X    $(NROFF) $(NROFFOPTS) < script.1 > script.man
  2141. X
  2142. Xscript.tidy.man: script.tidy.1 Makefile
  2143. X    $(NROFF) $(NROFFOPTS) < script.tidy.1 > script.tidy.man
  2144. X
  2145. Xreconnect.man: reconnect.1 Makefile
  2146. X    $(NROFF) $(NROFFOPTS) < reconnect.1 > reconnect.man
  2147. X
  2148. Xdisconnect.man: disconnect.1 Makefile
  2149. X    $(NROFF) $(NROFFOPTS) < disconnect.1 > disconnect.man
  2150. END_OF_FILE
  2151.   if test 4818 -ne `wc -c <'util/Makefile'`; then
  2152.     echo shar: \"'util/Makefile'\" unpacked with wrong size!
  2153.   fi
  2154.   # end of 'util/Makefile'
  2155. fi
  2156. echo shar: End of archive 3 \(of 6\).
  2157. cp /dev/null ark3isdone
  2158. MISSING=""
  2159. for I in 1 2 3 4 5 6 ; do
  2160.     if test ! -f ark${I}isdone ; then
  2161.     MISSING="${MISSING} ${I}"
  2162.     fi
  2163. done
  2164. if test "${MISSING}" = "" ; then
  2165.     echo You have unpacked all 6 archives.
  2166.     rm -f ark[1-9]isdone
  2167. else
  2168.     echo You still must unpack the following archives:
  2169.     echo "        " ${MISSING}
  2170. fi
  2171. exit 0
  2172. exit 0 # Just in case...
  2173.